<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="BbQdl" id="BbQdl"><span data-lake-id="u9393b219" id="u9393b219">典型回答</span></h1>
  <p data-lake-id="u20b7ef4e" id="u20b7ef4e"><br></p>
  <p data-lake-id="ua4b1749a" id="ua4b1749a"><span data-lake-id="ubdd0c914" id="ubdd0c914">在很多业务中，都需要和外部的一些机构进行交互，比如在电商场景，在发货环节，需要和各个快递公司做交互进行发货、物理更新。聚合支付场景需要和外部支付渠道做交互实现支付等。</span></p>
  <p data-lake-id="u5a0a5b76" id="u5a0a5b76"><span data-lake-id="uca2c3d8c" id="uca2c3d8c">​</span><br></p>
  <p data-lake-id="ua3d7476f" id="ua3d7476f"><span data-lake-id="u089c4561" id="u089c4561">很多时候，我们自己的可用性可以有一些保障的，但是，外部机构的可用性是没办法保证的，比如双十一大促期间，支付方式除了支付宝之外，还可能用银行卡支付，但是很难保证银联系统可以抗这么高的并发。、、</span></p>
  <p data-lake-id="u2af17ff8" id="u2af17ff8"><span data-lake-id="ua2db6edf" id="ua2db6edf">​</span><br></p>
  <p data-lake-id="ueb2a7d00" id="ueb2a7d00"><span data-lake-id="u91a805f8" id="u91a805f8">那么，遇到这样的情况，外部机构的SLA不可靠时，如何避免自己的应用不被拖垮呢？</span></p>
  <p data-lake-id="u7a1b5197" id="u7a1b5197"><span data-lake-id="u2e875758" id="u2e875758">​</span><br></p>
  <p data-lake-id="uea0cf7aa" id="uea0cf7aa"><span data-lake-id="u4395cd67" id="u4395cd67">主要有几个思路：</span></p>
  <p data-lake-id="u30260a90" id="u30260a90"><span data-lake-id="u34121321" id="u34121321">​</span><br></p>
  <p data-lake-id="u53f17579" id="u53f17579"><span data-lake-id="u5692aed7" id="u5692aed7">1、异步交互</span></p>
  <p data-lake-id="u1494de2e" id="u1494de2e"><span data-lake-id="uacc364ed" id="uacc364ed">2、文件交互</span></p>
  <p data-lake-id="uecaefd53" id="uecaefd53"><span data-lake-id="uef249ed7" id="uef249ed7">3、超时机制</span></p>
  <p data-lake-id="ud2c034f0" id="ud2c034f0"><span data-lake-id="ud3b235d0" id="ud3b235d0">4、限流降级熔断</span></p>
  <p data-lake-id="ufe366dd4" id="ufe366dd4"><span data-lake-id="u6ac4fc1d" id="u6ac4fc1d">5、业务取舍</span></p>
  <p data-lake-id="ucf42cfa2" id="ucf42cfa2"><span data-lake-id="ub0bfe257" id="ub0bfe257">​</span><br></p>
  <h3 data-lake-id="rxqea" id="rxqea"><span data-lake-id="u325e73e2" id="u325e73e2">异步交互</span></h3>
  <p data-lake-id="ua74c6b23" id="ua74c6b23"><br></p>
  <p data-lake-id="uf045a0ba" id="uf045a0ba"><span data-lake-id="u163f031c" id="u163f031c">首先比较容易想到的就是和机构之间不要进行同步交互，同步交互的话会把所有的流量都发送到外部合作方，并且本系统还要同步等结果，不仅会浪费系统资源，还会让系统整体响应变慢。</span></p>
  <p data-lake-id="u0f3ea07b" id="u0f3ea07b"><span data-lake-id="uf0d8f665" id="uf0d8f665">​</span><br></p>
  <p data-lake-id="udc08cc50" id="udc08cc50"><span data-lake-id="u53988dec" id="u53988dec">在有些场景中，可以考虑和机构进行异步交互。</span></p>
  <p data-lake-id="u08dfb3d0" id="u08dfb3d0"><span data-lake-id="u70a39614" id="u70a39614">​</span><br></p>
  <p data-lake-id="u33cc2630" id="u33cc2630"><span data-lake-id="uc99aa98c" id="uc99aa98c">比如，我们在电商网站上做一些金融产品的时候，比如天猫运费险，当用户下单以后，要给买家投保一笔运费险。</span></p>
  <p data-lake-id="u79a55ac0" id="u79a55ac0"><span data-lake-id="u2ed0b589" id="u2ed0b589">​</span><br></p>
  <p data-lake-id="ub453ae95" id="ub453ae95"><span data-lake-id="u13f603d1" id="u13f603d1">这个场景，运费险投保是必须要成功的，因为买家下单时已经看到自己有运费险了，所以必须要让他能享受这个服务。（如果有些用户不应该享受，那就应该在展示的时候就拦截，而不是先展示，后拒绝）</span></p>
  <p data-lake-id="uf873a0f1" id="uf873a0f1"><span data-lake-id="ua4ccc4de" id="ua4ccc4de">​</span><br></p>
  <p data-lake-id="ucb0292d1" id="ucb0292d1"><span data-lake-id="u57d3f73d" id="u57d3f73d">像这个场景，我们如果每一笔都去调保险公司的话，那大概率他们是扛不住这个业务量的。而运费险投保如果稍微晚一会，在小时级别的话，理论上对业务是无损的，因为一般不太可能几个小时内就发货，收货，退货。</span></p>
  <p data-lake-id="u750f47e7" id="u750f47e7"><span data-lake-id="u4d85a0ee" id="u4d85a0ee">​</span><br></p>
  <p data-lake-id="ud318271a" id="ud318271a"><span data-lake-id="u6c75489c" id="u6c75489c">所以，我们就可以异步的和外部的保险公司进行交互，通过定时任务或者延迟消息的方式，和保司交互，这样可以起到削峰填谷的作用，并且这个链路可以不断重试，即使失败了，也不会影响到正常的下单主流程。</span></p>
  <p data-lake-id="u9ebaa269" id="u9ebaa269"><span data-lake-id="ua96e3f18" id="ua96e3f18">​</span><br></p>
  <p data-lake-id="u39c23c0a" id="u39c23c0a"><span data-lake-id="u2c175af5" id="u2c175af5">​</span><br></p>
  <h3 data-lake-id="j67au" id="j67au"><span data-lake-id="u0ddb0d07" id="u0ddb0d07">文件交互</span></h3>
  <p data-lake-id="u6c7d5f84" id="u6c7d5f84"><br></p>
  <p data-lake-id="u987cd1f8" id="u987cd1f8"><span data-lake-id="u401ea248" id="u401ea248">文件交互是一种异步交互的极端例子，他在异步的基础上还做了批次。把之前的每单异步，变成了批量异步。</span></p>
  <p data-lake-id="u6f1667ee" id="u6f1667ee"><span data-lake-id="u751524b4" id="u751524b4">​</span><br></p>
  <p data-lake-id="u79751bf7" id="u79751bf7"><span data-lake-id="u32712844" id="u32712844">比如电商业务中，商家发货时，需要生成快递单号，但是这些快递单号如果实时去快递公司获取的话，那就有一定的失败的概率。</span></p>
  <p data-lake-id="u54a84b49" id="u54a84b49"><span data-lake-id="ua0004fde" id="ua0004fde">​</span><br></p>
  <p data-lake-id="u7e4a354c" id="u7e4a354c"><span data-lake-id="u7bd05b43" id="u7bd05b43">所以就可以事先先从快递公司申请一个批次的快递单号，然后自己本地发货时直接用，然后在批量的通知给快递公司就行了。</span></p>
  <p data-lake-id="u36c7731a" id="u36c7731a"><span data-lake-id="u4f65930f" id="u4f65930f">​</span><br></p>
  <p data-lake-id="u48fb65d2" id="u48fb65d2"><span data-lake-id="u85dfdbe6" id="u85dfdbe6">这种批量可以是一个接口调用，也可以用文件。用文件的好处就是甚至都不需要接口交互，只需要把文件生成好上传到FTP中，对方自己下载后解析就行了。</span></p>
  <p data-lake-id="u713acea3" id="u713acea3"><br></p>
  <h3 data-lake-id="kM2Hn" id="kM2Hn"><span data-lake-id="u2755e1b0" id="u2755e1b0">超时机制</span></h3>
  <p data-lake-id="u89bbe795" id="u89bbe795"><br></p>
  <p data-lake-id="ufad2d475" id="ufad2d475"><span data-lake-id="u0ba0b134" id="u0ba0b134">在做外部接口交互时，并不是所有的情况都可以做异步，比如说高德的聚合打车。</span></p>
  <p data-lake-id="u84d1360b" id="u84d1360b"><span data-lake-id="ud0a58d80" id="ud0a58d80">​</span><br></p>
  <p data-lake-id="u3c13dc0d" id="u3c13dc0d"><span data-lake-id="u0d5ff541" id="u0d5ff541">当我们输入完出发点和目的地之后开始叫车时，他就需要实时的和各个租车平台对接交互，然后分发这笔订单。</span></p>
  <p data-lake-id="ua5dd077f" id="ua5dd077f"><span data-lake-id="u44674f7e" id="u44674f7e">​</span><br></p>
  <p data-lake-id="udba02983" id="udba02983"><span data-lake-id="ude1ff02f" id="ude1ff02f">这个过程就要同步交互，但是我们需要给每个第三方平台都设置一个请求的超时时间，比如2秒钟，超过2秒钟就自动中断了。而不是让用户一直在前端的等。</span></p>
  <p data-lake-id="ud1432a34" id="ud1432a34"><span data-lake-id="ub44d79ca" id="ub44d79ca">​</span><br></p>
  <p data-lake-id="u5ab63647" id="u5ab63647"><span data-lake-id="u4e65a04b" id="u4e65a04b">并且根据这种外部接口的响应时间的数据，我们可以做一些动态的负载均衡，把更多的流量分发给性能更好的服务商。</span></p>
  <p data-lake-id="u27cf9b21" id="u27cf9b21"><span data-lake-id="u4cd742a2" id="u4cd742a2">​</span><br></p>
  <p data-lake-id="u4de77d94" id="u4de77d94"><span data-lake-id="u23921961" id="u23921961">​</span><br></p>
  <h3 data-lake-id="EnGU0" id="EnGU0"><span data-lake-id="ucab4f2d2" id="ucab4f2d2">限流降级熔断</span></h3>
  <p data-lake-id="u615d6bf6" id="u615d6bf6"><br></p>
  <p data-lake-id="u7a76fafb" id="u7a76fafb"><span data-lake-id="u99524c57" id="u99524c57">接口如果超时很严重，我们也需要对他做限流、降级和熔断。</span></p>
  <p data-lake-id="ub9596a65" id="ub9596a65"><span data-lake-id="u7e614e36" id="u7e614e36">​</span><br></p>
  <p data-lake-id="u41e8a647" id="u41e8a647"><span data-lake-id="u97b4da5e" id="u97b4da5e">限流：就是假如他的接口就能扛100QPS，那么我们就需要不能给他超过100的并发请求，那样他会处理不过来，导致整体性能下降。</span></p>
  <p data-lake-id="u030bbfef" id="u030bbfef"><span data-lake-id="u124c5ebf" id="u124c5ebf">​</span><br></p>
  <p data-lake-id="ue4cdddd9" id="ue4cdddd9"><span data-lake-id="u9b4c39fb" id="u9b4c39fb">降级：假如查询一个用户中心的服务查用户名，但是接口响应慢，那么就可以暂时降级，直接返回"陌生人"或者“用户名加载中”等信息。</span></p>
  <p data-lake-id="u5d006207" id="u5d006207"><span data-lake-id="u77bad9ec" id="u77bad9ec">​</span><br></p>
  <p data-lake-id="u8e0f944d" id="u8e0f944d"><span data-lake-id="u1d7b4b8f" id="u1d7b4b8f">熔断：假如外部某个接口特别慢，那么就可以干脆就不要再调他了。</span></p>
  <p data-lake-id="uc08ab316" id="uc08ab316"><span data-lake-id="u6e73a622" id="u6e73a622">​</span><br></p>
  <p data-lake-id="u03de38ae" id="u03de38ae"><span data-lake-id="u6ac1b63e" id="u6ac1b63e">这样做对业务是有损的。比如大促当天，银联的接口性能太差了，我们把银联降级掉，那么用户就会无法用银联支付了。对用户来说就少了个选择。</span></p>
  <p data-lake-id="u4535e721" id="u4535e721"><span data-lake-id="u1bc765f2" id="u1bc765f2">​</span><br></p>
  <p data-lake-id="ub73f13c1" id="ub73f13c1"><span data-lake-id="u61249079" id="u61249079">但是对于我们的系统来说，起到了很好的保护作用。可以在外部接口性能恢复以后再恢复调用就行了。</span></p>
  <p data-lake-id="u6cae34a6" id="u6cae34a6"><span data-lake-id="ue9608593" id="ue9608593">​</span><br></p>
  <p data-lake-id="uc77c5d53" id="uc77c5d53"><br></p>
  <p data-lake-id="ucaef1739" id="ucaef1739"><br></p>
  <h3 data-lake-id="TOt9H" id="TOt9H"><span data-lake-id="uda6718e9" id="uda6718e9">业务取舍</span></h3>
  <p data-lake-id="u206e7a93" id="u206e7a93"><br></p>
  <p data-lake-id="u45a43c79" id="u45a43c79"><span data-lake-id="uec158daa" id="uec158daa">大家知道最开始余额宝被做出来主要是干嘛的吗？其实最初是为了解决支付成功率低的问题的。</span></p>
  <p data-lake-id="udac545b5" id="udac545b5"><span data-lake-id="u40b0c69b" id="u40b0c69b">​</span><br></p>
  <p data-lake-id="udc6c3d3e" id="udc6c3d3e"><span data-lake-id="ucebe63ec" id="ucebe63ec">大促期间就是因为银联等外部渠道支付成功率太低了，但是很多人又因为银行有收益所以把钱存在银行。</span></p>
  <p data-lake-id="u1436b525" id="u1436b525"><span data-lake-id="ude73227a" id="ude73227a">​</span><br></p>
  <p data-lake-id="uddbf623b" id="uddbf623b"><span data-lake-id="u309c449b" id="u309c449b">那为了解决这个问题，一个好的办法，就是在业务上给用户多一个选择，让用户减少使用银行卡支付的概率。</span></p>
  <p data-lake-id="u6af706c7" id="u6af706c7"><span data-lake-id="uffce4af7" id="uffce4af7">​</span><br></p>
  <p data-lake-id="uce4e995c" id="uce4e995c"><span data-lake-id="u12f591b7" id="u12f591b7">就假如说，高德聚合打车，发现外部服务商技术都太差了，他做了自营，是不是也能大幅度降低对外部机构的依赖问题呢？</span></p>
 </body>
</html>